#pragma once
#include <GL\glui.h>
#include <vector>
#include <utility>
#include <cmath>
#include <string>
#include <sstream>
#include <map>
#include "Player.h"
#include "Animation.h"
#include "Move.h"
#include "Communication.h"
#include "Camera.h"
#include "Material.h"

#include <windows.h>
#define getCurrentTime GetTickCount

using std::vector;
using std::pair;
using std::string;
using std::stringstream;
using std::map;


struct BoardCell{
	int x;
	int y;
	PlayerType player;
	int nCheckers;
};

struct GameState{
	BoardCell cells[8][8];
	Move move;
	int white_n_checkers;
	int black_n_checkers;
};

enum GameStatus{CHECKER_CHOICE,MOVE_CHOICE, COMP_CHOICE,ANIMATION,HOLD};
enum ApplicationStatus{INITIAL,GAME,END_GAME,GAME_FILM};

class Board
{
public:
	float size;
	float cellSize;
	unsigned int txId;
	BoardCell cells[8][8];
	float white_board_z, black_board_z;
	int white_board_ncheckers, black_board_ncheckers;

	float checkerRadius;
	float checkerHeight;
	GLUquadric* glQ;

	vector< pair<int, int> > selected;
	vector< pair<int,int> > player_positions;//usado no caso do jogador anular o movimento que ia fazer

	PlayerType turn;
	PlayerControl white_player;
	PlayerControl black_player;
	int white_n_checkers;
	int black_n_checkers;

	int move_initial_pos;
	map<int, Move> valid_moves; 

	ApplicationStatus application_status;
	GameStatus game_status;
	AnimationStatus ani_status;
	AnimationData animation;
	RemoveAnimation remove_animation;
	RemoveAnimationStatus remove_animation_status;
	CapturedAnimation captured_animation;
	CapturedAnimationStatus captured_animation_status; 
	
	vector<GameState> states;
	int game_film_turn;

	Board(void);
	~Board(void);
	Board(PlayerControl white_player, PlayerControl black_player, float cellSize, unsigned int txId, float delta_t, float v);//, bool timer, int maximum_time);
	
	string toString();
	PlayerControl getCurrentPlayerControl();
	void setValidMoves(vector<Move> moves);

	void drawBoard(GLenum mode);
	void drawChecker(PlayerType player);
	void drawCheckerStack(PlayerType player, int n_checker);
	void drawBoardStacks();
	void drawSelected(GLenum mode, bool visible);
	void draw(GLenum mode, float xy_aspect, float* obj_pos, float* view_rotate);

	void changeTurn();

	//animation
	void initializeAnimation(Move move);
	void finalizeMove();
	void initializeGameFilm();

	void undo();
	
	float delta_t, v;
	void drawAnimation();

	bool timer;
	bool timer_on;
	int maximum_time;
	int current_time;
	int end_time;

	void initializeTimer();


	Camera camera_white;
	Camera camera_black;
	Camera camera_black_white;
	Camera camera_white_black;
	Cam current_cam;
	AnimationCamera ani_camera;
	AnimationCameraStatus ani_camera_status;
	void setCamera(float xy_aspect, float* obj_pos, float* view_rotate);
	void initializeCameraAnimation(Cam final_cam);
	
	void write_string(char* s, int length);
	void showText(int window_w, int window_h);

	void updateAnimation();
	void updateRemoveAnimation();

	Material white_material;
	Material black_material;
	Material board_material;
	Material selected_material;
};

